const Base64 = new class {
	constructor() {
		this.decoder$1;
		this.b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		this.b64pad = "=";
	}
	decode2(a) {
		var i;
		if (this.decoder$1 === undefined) {
			var b64 = this.b64map;
			var ignore = "= \f\n\r\t\u00A0\u2028\u2029";
			this.decoder$1 = Object.create(null);
			for (i = 0; i < 64; ++i) {
				this.decoder$1[b64.charAt(i)] = i;
			}
			for (i = 0; i < ignore.length; ++i) {
				this.decoder$1[ignore.charAt(i)] = -1;
			}
		}
		var out = [];
		var bits = 0;
		var char_count = 0;
		for (i = 0; i < a.length; ++i) {
			var c = a.charAt(i);
			if (c == "=") {
				break;
			}
			c = this.decoder$1[c];
			if (c == -1) {
				continue;
			}
			if (c === undefined) {
				throw new Error("Illegal character at offset " + i);
			}
			bits |= c;
			if (++char_count >= 4) {
				out[out.length] = (bits >> 16);
				out[out.length] = (bits >> 8) & 0xFF;
				out[out.length] = bits & 0xFF;
				bits = 0;
				char_count = 0;
			} else {
				bits <<= 6;
			}
		}
		switch (char_count) {
			case 1:
				throw new Error("Base64 encoding incomplete: at least 2 bits missing");
			case 2:
				out[out.length] = (bits >> 10);
				break;
			case 3:
				out[out.length] = (bits >> 16);
				out[out.length] = (bits >> 8) & 0xFF;
				break;
		}
		return out;
	}

	hex2b64(h) {
		var i;
		var c;
		var ret = "";
		let b64map = this.b64map;
		let b64pad = this.b64pad;
		for (i = 0; i + 3 <= h.length; i += 3) {
			c = parseInt(h.substring(i, i + 3), 16);
			ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
		}
		if (i + 1 == h.length) {
			c = parseInt(h.substring(i, i + 1), 16);
			ret += b64map.charAt(c << 2);
		} else if (i + 2 == h.length) {
			c = parseInt(h.substring(i, i + 2), 16);
			ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
		}
		while ((ret.length & 3) > 0) {
			ret += b64pad;
		}
		return ret;
	}
	
	//此方法结果异常
	// b64toBA(s) {
	// 	// piggyback on b64tohex for now, optimize later
	// 	const h = this.decode2(s);
	// 	return h.length & 0x01 ? [] : h.match(/\w{2}/g).map(i =>parseInt(i, 16));
	// }

	bAtoB64(buffer) {
		const hexArr = Array.prototype.map.call(
			new Uint8Array(buffer),
			function (bit) {
				var hex = bit.toString(16)
				return hex.length & 0x01 ? ('0' + hex) : hex;
			}
		)
		return this.hex2b64(hexArr.join(""));
	}

	uint6ToB64(nUint6) {
		return nUint6 < 26 ?
			nUint6 + 65 :
			nUint6 < 52 ?
			nUint6 + 71 :
			nUint6 < 62 ?
			nUint6 - 4 :
			nUint6 === 62 ?
			43 :
			nUint6 === 63 ?
			47 :
			65;
	}

	base64EncArr(aBytes) {
		const eqLen = (3 - (aBytes.length % 3)) % 3;
		let	sB64Enc = "";
		for (let nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
			nMod3 = nIdx % 3;
			/* Uncomment the following line in order to split the output in lines 76-character long: */
			/*
			if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
			*/
			nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
			if (nMod3 === 2 || aBytes.length - nIdx === 1) {
				sB64Enc += String.fromCharCode(this.uint6ToB64(nUint24 >>> 18 & 63), this.uint6ToB64(nUint24 >>> 12 & 63), this.uint6ToB64(nUint24 >>> 6 & 63), this.uint6ToB64(nUint24 & 63));
				nUint24 = 0;
			}
		}
		return eqLen === 0 ?
			sB64Enc :
			sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
	}

	b64ToUint6 (nChr) {
		return nChr > 64 && nChr < 91 ?
				nChr - 65
			: nChr > 96 && nChr < 123 ?
				nChr - 71
			: nChr > 47 && nChr < 58 ?
				nChr + 4
			: nChr === 43 ?
				62
			: nChr === 47 ?
				63
			:
				0;
	
	}
	
	base64DecToArr (sBase64, nBlockSize) {
		var
			sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
			nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);
	
		for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
			nMod4 = nInIdx & 3;
			nUint24 |= this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
			if (nMod4 === 3 || nInLen - nInIdx === 1) {
				for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
					aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
				}
				nUint24 = 0;
			}
		}
	
		return aBytes;
	}
	bA2B64(buffer) {
		return this.base64EncArr(new Uint8Array(buffer));
	}
}
export {
	Base64
};